using MapsterMapper;
using AiQiuQuan.Sport.Model.Models;
using AiQiuQuan.Sport.Core;
using AiQiuQuan.Sport.WebApi.Entities;
using AiQiuQuan.Sport.WebApi.Repositories;
using Microsoft.EntityFrameworkCore;
using AiQiuQuan.Sport.WebApi.Core;
using AiQiuQuan.Sport.Core.Tool;
using AiQiuQuan.Sport.Core.AspNetCore;
using Microsoft.Extensions.Caching.Memory;
using System.Web;

namespace AiQiuQuan.Sport.WebApi.Services.Impl
{
    /// <summary>
    /// 平台管理用户表管理
    /// </summary>
    public class FrameworkUsersService : IFrameworkUsersService
    {
        private readonly IMapper _mapper;
        private readonly IMemoryCache _cache;
        private readonly IUnitOfWorkManager _unitOfWorkManager;
        private readonly IFrameworkUsersRepository _frameworkUsersRepository;
        private readonly ICurrentInfo _currentInfo;
        private readonly IFrameworkUserRolesRepository _userRoleRepository;
        private readonly IFrameworkRolesRepository _frameworkRolesRepository;
        private readonly IVenueInfoRepository _venueInfoRepository;

        /// <summary>
        /// ctor
        /// </summary>
        public FrameworkUsersService(
            IMapper mapper,
            IMemoryCache cache,
            IUnitOfWorkManager unitOfWorkManager,
            IFrameworkUsersRepository frameworkUsersRepository,
            ICurrentInfo currentInfo,
            IFrameworkUserRolesRepository userRoleRepository,
            IFrameworkRolesRepository frameworkRolesRepository,
            IVenueInfoRepository venueInfoRepository)
        {
            _mapper = mapper;
            _cache = cache;
            _unitOfWorkManager = unitOfWorkManager;
            _frameworkUsersRepository = frameworkUsersRepository;
            _currentInfo = currentInfo;
            _userRoleRepository = userRoleRepository;
            _frameworkRolesRepository = frameworkRolesRepository;
            _venueInfoRepository = venueInfoRepository;
        }

        /// <summary>
        /// 登录
        /// </summary>
        public async Task<UnaryResult<FrameworkUsersLoginResultDto>> LoginAsync(FrameworkUsersLoginDto request)
        {
            var user = await _frameworkUsersRepository.AsNoTracking()
                .FirstOrDefaultAsync(m => m.ITCode == request.Code && m.Password == Tool.ToMd5(request.Password));
            if (user == null)
            {
                return UnaryResult.From<FrameworkUsersLoginResultDto>(10, null, "账号密码错误");
            }

            var result = new FrameworkUsersLoginResultDto
            {
                User = _mapper.Map<FrameworkUsersDto>(user),
                RoleList = await GetUserRoleListAsync(user.ITCode),
                Token = HttpUtility.UrlEncode(AESCryptography.Encrypt($"{user.ID}|{user.Name}|1", SimpleAuthHandler.AES_KEY))
            };
            _cache.Set(user.ID.ToString(), result.Token, new TimeSpan(0, SimpleAuthHandler.ExpireMinute, 0));

            return UnaryResult.Succeed(result);
        }

        /// <summary>
        /// 注销登录
        /// </summary>
        public async Task<UnaryResult> LogOutAsync()
        {
            _cache.Remove(_currentInfo.UserId.ToString());
            return await Task.FromResult(UnaryResult.Succeed());
        }

        /// <summary>
        /// 查询一条记录
        /// </summary>
        public async Task<FrameworkUsersDto> GetAsync(Guid id)
        {
            var frameworkUsers = await _frameworkUsersRepository.FirstOrDefaultAsync(m => m.ID == id);
            return _mapper.Map<FrameworkUsers, FrameworkUsersDto>(frameworkUsers);
        }

        /// <summary>
        /// 查询用户及角色
        /// </summary>
        public async Task<FrameworkUsersLoginResultDto> QueryAsync()
        {
            var user = await _frameworkUsersRepository.FirstOrDefaultAsync(m => m.ID == _currentInfo.UserId);
            if (user == null)
            {
                return null;
            }

            var result = new FrameworkUsersLoginResultDto
            {
                User = _mapper.Map<FrameworkUsersDto>(user),
                RoleList = await GetUserRoleListAsync(user.ITCode)
            };
            return result;
        }

        /// <summary>
        /// 新增
        /// </summary>
        public async Task<UnaryResult> AddAsync(FrameworkUsersAddDto model)
        {
            var frameworkUsers = _mapper.Map<FrameworkUsers>(model);

            using (var uow = _unitOfWorkManager.Begin())
            {
                await _frameworkUsersRepository.AddAsync(frameworkUsers);
                await uow.CompleteAsync();
            }

            return UnaryResult.Succeed();
        }

        /// <summary>
        /// 修改
        /// </summary>
        public async Task<UnaryResult> UpdateAsync(FrameworkUsersUpdateDto model)
        {
            var frameworkUsers = await _frameworkUsersRepository.FirstOrDefaultAsync(m => m.ID == model.ID);
            _mapper.Map(model, frameworkUsers);

            using (var uow = _unitOfWorkManager.Begin())
            {
                await _frameworkUsersRepository.UpdateAsync(frameworkUsers);

                await uow.CompleteAsync();
            }

            return UnaryResult.Succeed();
        }

        /// <summary>
        /// 删除
        /// </summary>
        public async Task<UnaryResult> DeleteAsync(Guid id)
        {
            await _frameworkUsersRepository.DeleteAsync(p => p.ID == id);
            return UnaryResult.Succeed();
        }

        /// <summary>
        /// 用户角色列表
        /// </summary>
        /// <param name="userCode">用户CODE</param>
        public async Task<List<FrameworkUserRoleDto>> GetUserRoleListAsync(string userCode)
        {
            var queryable = from userRole in _userRoleRepository.AsNoTracking()
                            join role in _frameworkRolesRepository.AsNoTracking()
                            on userRole.RoleCode equals role.RoleCode
                            where userRole.UserCode == userCode
                            select new FrameworkUserRoleDto
                            {
                                RoleCode = role.RoleCode,
                                RoleName = role.RoleName,
                                UserCode = userRole.UserCode
                            };
            return await queryable.ToListAsync();
        }

        /// <summary>
        /// 我管理的场馆分页列表
        /// </summary>
        public async Task<PageResult<VenueInfoDto>> GetMyVenuePageListAsync(PageRequest request)
        {
            var queryable = _venueInfoRepository.AsNoTracking();
            var rolelist = await GetFrameworkUserRoleListAsync();
            if (!rolelist.Any() || (!rolelist.Any(m => m.RoleCode == FrameworkRoleConst.SYS_ADMIN) && !rolelist.Any(m => m.RoleCode == FrameworkRoleConst.VENUE_MANAGE)))
            {
                queryable = queryable.Where(m => false);
            }
            else if (rolelist.Any(m => m.RoleCode == FrameworkRoleConst.VENUE_MANAGE))
            {
                queryable = queryable.Where(m => _frameworkUsersRepository.AsNoTracking().Any(j => j.ID == _currentInfo.UserId && j.VenueInfoID == m.ID));
            }

            var list = await queryable.Select(m => _mapper.Map<VenueInfoDto>(m)).OrderBy(m => m.CreateTime).PageListAsync(request);
            return list;
        }

        #region private methods
        /// <summary>
        /// 当前用户角色列表
        /// </summary>
        private async Task<List<FrameworkUserRoles>> GetFrameworkUserRoleListAsync()
        {
            var queryable = from fuserrole in _userRoleRepository.AsNoTracking()
                            join fuser in _frameworkUsersRepository.AsNoTracking()
                            on fuserrole.UserCode equals fuser.ITCode
                            where fuser.ID == _currentInfo.UserId
                            select fuserrole;
            var rolelist = await queryable.ToListAsync();
            return rolelist;
        }
        #endregion
    }
}
